import React, {useEffect, useMemo, useRef, useState} from "react"
import {Button, Col, Form, InputNumber, InputRef, Row, Select, Space} from "antd";
import {PlusOutlined, SearchOutlined} from "@ant-design/icons";
import {BaseSelectRef} from "rc-select";
import {
    getAllGoodsSummaries,
    GoodsSummary,
    GoodsUnitResponse,
    QueryGoodsRequest,
    QueryGoodsUnitResponse, SubGoodsResponse
} from "../apis/GoodsApi";
import {it} from "node:test";
import {NumberIdAndName} from "../types/BasicModels";
import {data} from "browserslist";
import GoodsUnitSelect from "./GoodsUnitSelect";
import {useLiveQuery} from "dexie-react-hooks";
import {GoodsAmountAndUnitUseHistory, myDatabase} from "../database/MyDatabase";

export interface EditFormItemRowProps<T, E> {
    onFinish: (values: T) => Promise<void>
    existedGoodsKeys: SelectedGoodsKey[]
    request?: QueryGoodsRequest
    withAmount?: boolean
    withPrice?:boolean
    fetchGoods?: () => Promise<E[]>
    optionRender?: (item: E,) => React.ReactNode
    availableAmountAndUnitHistories?: GoodsAmountAndUnitUseHistory []
}

export interface EditOrderItemRowFormData {
    amount: number
    goodsId: string
    unitId?: number
    price?:number
}

export interface FinalEditOrderItemRowFormData {
    amount: number
    goodsId: number
    subGoodsId?: number
    unitId?: number
    price?:number
}

export interface EditOrderItemGoodsData {
    id: number
    name: string
    barcode: string
    units?: QueryGoodsUnitResponse[]
    subGoods?: SubGoodsResponse
    rememberedPrice?: number
    rememberedAmount?:number
    rememberedUnitId?:number
}

export interface SelectedGoodsKey {
    goodsId: number
    subGoodsId?: number
}

const EditOrderItemRow = function <E extends EditOrderItemGoodsData = EditOrderItemGoodsData>(props: EditFormItemRowProps<FinalEditOrderItemRowFormData, E>) {
    const [goodsSummaries, setGoodsSummaries] = useState<E[]>([])
    useEffect(() => {
        (async () => {
            let data: E[]
            if (props.fetchGoods) {
                data = await props.fetchGoods()
            } else {
                let list: EditOrderItemGoodsData[] = (await getAllGoodsSummaries(props.request)).data.flatMap(it => {
                    if (it.subGoodsList && !!it.subGoodsList.length) {
                        return it.subGoodsList.map(subGoods => ({
                            ...it,
                            units:[],
                            subGoods: subGoods
                        }))
                    } else {
                        return [it]
                    }
                });
                data = list as E[]
            }
            setGoodsSummaries(data)
        })()
    }, [])
    const [form] = Form.useForm()
    const [loading, setLoading] = useState(false)
    const searchGoodsRef = useRef<BaseSelectRef>(null);
    const numberInputRef = useRef<HTMLInputElement>(null);
    const priceInputRef = useRef<HTMLInputElement>(null);
    const withAmount = props.withAmount !== false;
    const withPrice = !!props.withPrice;

    const selectUnitRef = useRef<BaseSelectRef>(null);
    const [selectedGoodsKey, setSelectedGoodsKey] = useState<SelectedGoodsKey>()
    const selectedGoods = useMemo(() => {
        if (selectedGoodsKey) {
            return goodsSummaries.find(item => item.id === selectedGoodsKey.goodsId && item.subGoods?.id === selectedGoodsKey.subGoodsId);
        } else {
            return undefined;
        }
    }, [selectedGoodsKey]);
    const units = useMemo(() => {
        if (selectedGoods) {
            return selectedGoods.units
        } else {
            return undefined
        }
    }, [selectedGoods]);
    const basicUnit = useMemo(() => {
        return units?.find(e => e.basicMultiple === 0)
    }, [units]);
    useEffect(() => {
        let history = props.availableAmountAndUnitHistories?.find(history => history.goodsId === selectedGoods?.id);
        if (units?.length && selectedGoods) {
            form.setFieldValue("unitId", selectedGoods?.rememberedUnitId??history?.unitId ?? basicUnit?.id ?? units?.[0]?.id)
            form.setFieldValue("amount", selectedGoods?.rememberedAmount??history?.amount ?? 1)
        }
        if(selectedGoods){
            form.setFieldValue("price",history?.price??selectedGoods.rememberedPrice??0)
        }
    }, [units, selectedGoods]);

    function stringToGoodsKey(string: string) {
        let idSplitList = string.split("-");
        return {goodsId: Number(idSplitList[0]), subGoodsId: idSplitList[1] ? Number(idSplitList[1]) : undefined};
    }

    function onChangeSelectedValue(value: string) {
        if (withAmount) {
            setSelectedGoodsKey(stringToGoodsKey(value))
            setTimeout(() => {
                numberInputRef.current?.focus()
                numberInputRef.current?.select()
            }, 100)
        } else {
            form.submit()
        }
    }

    // @ts-ignore
    return (
        <Form<EditOrderItemRowFormData> form={form} initialValues={{
            amount: 1
        }} onFinish={(values) => {
            setLoading(true)
            let key = stringToGoodsKey(values.goodsId);
            props.onFinish({
                ...values,
                ...key
            }).then(() => {
                form.resetFields()
                setTimeout(() => {
                    searchGoodsRef?.current?.focus()
                }, 100)
            }).finally(() => {
                setLoading(false)
                setSelectedGoodsKey(undefined)
            })
        }}>
            <Row style={{display: "flex", flexDirection: "row"}} gutter={16}>
                <Col span={20-[withAmount,withAmount,withPrice].filter(it=>it).length * 4}>
                    <Form.Item rules={[{required: true}]} name={"goodsId"} label={"货品"}>
                        <Select<string> style={{width: "100%"}}
                                        showSearch
                                        onSelect={value => () => {
                                            onChangeSelectedValue(value)
                                        }}
                                        onChange={(value, option) => {
                                            onChangeSelectedValue(value);
                                        }}
                                        ref={searchGoodsRef}
                                        suffixIcon={<SearchOutlined/>}
                                        filterOption={(inputValue, option) => {
                                            let value = option?.value?.toString()!!;
                                            let strings = value.split("-");
                                            let id = Number(strings[0])
                                            let goods = goodsSummaries.find(it => it.id === id && (!strings[1] || Number(strings[1]) === it.subGoods?.id));
                                            inputValue = inputValue.toLowerCase().trim()
                                            return !!(goods?.name?.toLowerCase()?.includes(inputValue) || goods?.barcode?.toLowerCase()?.includes(inputValue) || goods?.subGoods?.number?.toLowerCase()?.includes(inputValue) || goods?.subGoods?.name?.toLowerCase()?.includes(inputValue))
                                        }}
                                        placeholder={"条码、名称"}
                                        optionRender={props.optionRender ? (item) => {
                                            let goods = goodsSummaries.find(it => (it.subGoods ? it.id + "-" + it.subGoods.id : it.id) == item.value);
                                            return goods ? props.optionRender!(goods) : undefined;
                                        } : undefined}
                                        options={goodsSummaries.map(it => {
                                            return ({
                                                label: <div style={{display: 'flex', flexDirection: "column"}}>
                                                    <Space>
                                                        <span>{it.subGoods ? it.barcode + "|" + it.subGoods.number : it.barcode}</span>
                                                        <span>{it.subGoods ? it.subGoods.name + `（${it.name}）` : it.name}</span>
                                                    </Space>
                                                </div>,
                                                value: it.subGoods ? it.id + "-" + it.subGoods.id : it.id.toString(),
                                                disabled: props?.existedGoodsKeys.some(item => item.goodsId === it.id && item.subGoodsId === it.subGoods?.id),
                                            });
                                        })}/>
                    </Form.Item>
                </Col>
                {
                    withAmount && <>
                        <Col span={4}>
                            <Form.Item rules={[{required: true}, {type: "number", min: 0}]} name={"amount"} label={"数量"}>
                                <InputNumber ref={numberInputRef} style={{width: "100%"}} onPressEnter={() => {
                                    if (units?.length) {
                                        selectUnitRef.current?.focus()
                                    } else {
                                        form.submit()
                                    }
                                }}/>
                            </Form.Item>
                        </Col>

                        {
                            !!units?.length &&
                            <Col span={4}>
                                <Form.Item label={"单位"} name={"unitId"}>
                                    <GoodsUnitSelect units={units} ref={selectUnitRef} onKeyDown={(event) => {
                                        if(event.key==="Enter") {
                                            if(withPrice) {
                                                setTimeout(() => {
                                                    priceInputRef?.current?.focus()
                                                }, 100)
                                            }else {
                                                form.submit()
                                            }
                                        }
                                    }}
                                    />
                                </Form.Item>
                            </Col>
                        }

                    </>
                }

                {withPrice && <Col span={4}>
                    <Form.Item rules={[{required: true}, {type: "number", min: 0}]} name={"price"} label={"价格"}>
                        <InputNumber ref={priceInputRef} style={{width: "100%"}} onPressEnter={() => {
                            form.submit()
                        }}/>
                    </Form.Item>
                </Col>}

                <Col span={4}>
                    <Button loading={loading} type={"primary"} onClick={() => {
                        form.submit()
                    }}><PlusOutlined/>添加</Button>
                </Col>
            </Row>
        </Form>
    )
}

export default EditOrderItemRow
